package com.sunlands.qdcy.tongzhuo.web;

import com.qcloud.cos.COSClient;
import com.sunlands.qdcy.tongzhuo.common.annotation.AuthSig;
import com.sunlands.qdcy.tongzhuo.common.annotation.AutoLog;
import com.sunlands.qdcy.tongzhuo.config.COSConfig;
import com.sunlands.qdcy.tongzhuo.constant.*;
import com.sunlands.qdcy.tongzhuo.constant.dic.DIARY_ADVERT;
import com.sunlands.qdcy.tongzhuo.constant.dic.POSTGRADUATE_DIARY_ADVERT;
import com.sunlands.qdcy.tongzhuo.constant.dic.STUDY_OPEN_DAYS;
import com.sunlands.qdcy.tongzhuo.feign.SocketClient;
import com.sunlands.qdcy.tongzhuo.feign.UserFriendClient;
import com.sunlands.qdcy.tongzhuo.feign.vo.BuryingPointVO;
import com.sunlands.qdcy.tongzhuo.feign.vo.UserBlacklist;
import com.sunlands.qdcy.tongzhuo.feign.vo.UserInfoDTO;
import com.sunlands.qdcy.tongzhuo.model.DiaryDO;
import com.sunlands.qdcy.tongzhuo.model.DiaryTopicDO;
import com.sunlands.qdcy.tongzhuo.model.DicDO;
import com.sunlands.qdcy.tongzhuo.model.UserDiaryZanDO;
import com.sunlands.qdcy.tongzhuo.service.*;
import com.sunlands.qdcy.tongzhuo.util.CompareStrSimUtil;
import com.sunlands.qdcy.tongzhuo.util.DateUtil;
import com.sunlands.qdcy.tongzhuo.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.util.Pair;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.sunlands.qdcy.tongzhuo.common.annotation.AutoLog.Level.DEBUG;
import static com.sunlands.qdcy.tongzhuo.constant.CommonResultMessage.*;
import static com.sunlands.qdcy.tongzhuo.constant.dic.DIARY_ADVERT.*;
import static com.sunlands.qdcy.tongzhuo.vo.BusinessResult.createInstance;
import static com.sunlands.qdcy.tongzhuo.vo.BusinessResult.createSuccessInstance;

/**
 * @author anjl
 * @date 2019/5/2915:50
 */
@SuppressWarnings("unused")
@Api(tags = "1、用户日记相关")
@RestController
@Slf4j
@RequestMapping("/user/diary")
public class DiaryController extends BaseController {
    public static final float SIMILARITY_RATIO = 80;
    public static final int SIMILARITY_RATIO_COUNT = 4;

    @AutoLog
    @ApiOperation(value = "发布日记", notes = "发布日记", position = 10)
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    @PostMapping("/publish")
    public BusinessResult<DiaryDO> publishDiary(@RequestBody DiaryDTO diaryDTO) {

        //去图片url空字符串
        if (Objects.nonNull(diaryDTO.getImgUrls())) {
            diaryDTO.setImgUrls(diaryDTO.getImgUrls().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()));
        }
        diaryDTO.validate();
        //敏感词替换
        BusinessResult replaceContent = socketClient.replaceContent(CheckVO.builder().content(diaryDTO.getContent()).build());
        if (Objects.nonNull(replaceContent.getData())) {
            diaryDTO.setContent(replaceContent.getData().toString());
        }
//        if (checkContent.getCode().equals(CON_SENSITIVE.code)) {
//            throw new SensitiveException("日记内容： " + diaryDTO.getContent() + "\n敏感词：" + checkContent.getMessage());
//        }

        List<DiaryDO> lately1HourDiary = diaryService.findLately1HourDiary(currentUserId());
        if (lately1HourDiary.size() >= 10) {
            return createInstance(SIMILARITY_RATIO_LIMIT.code, "您已连续发表多次内容，请稍后再试吧~");
        }
        //大于30字的日记再检测
        if (diaryDTO.getContent().length() > 30) {
            if (lately1HourDiary.stream().filter(exist ->
                    CompareStrSimUtil.getSimilarityRatio(exist.getContent(), diaryDTO.getContent(), true) > SIMILARITY_RATIO)
                    .count() >= SIMILARITY_RATIO_COUNT) {
                return createInstance(SIMILARITY_RATIO_LIMIT);
            }
        }

        DiaryTopicDO topic;

        DiaryDO diaryDO = from(diaryDTO);
        diaryDO.setCreateType(DiaryDO.CreateTypeEnums.CREATE_BY_SELF.type);
        if (Objects.nonNull(diaryDTO.getTopicId())) {
            topic = topicService.findDiaryTopic(diaryDTO.getTopicId());
            if (Objects.isNull(topic)) {
                throw new IllegalArgumentException("topic 话题不存在！！topicId = " + diaryDTO.getTopicId());
            }
            diaryDO.setTopicName(topic.getTopic());
        }

        DiaryDO diaryDOSave = diaryService.save(diaryDO);
        if (Objects.nonNull(diaryDOSave.getTopicId())) {
            topicService.modifyTopicHot("0", diaryDTO.getTopicId());
        }
        return createSuccessInstance(diaryDOSave);
    }

    private DiaryDO from(DiaryDTO diaryDTO) {
        return DiaryDO.builder()
                .content(diaryDTO.getContent())
                .imgUrls(diaryDTO.getImgUrls().isEmpty() ? null : StringUtils.join(diaryDTO.getImgUrls(), ","))
                .topicId(diaryDTO.getTopicId())
                .userId(currentUserId())
                .build();
    }


    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "日记详情-查询", notes = "日记详情查询", position = 15)
    @AuthSig
    @GetMapping("/{id}")
    public BusinessResult findDetailById(HttpServletRequest request,
                                         @PathVariable Long id) {
        Long currentUserId = currentUserId();
        DiaryDO diaryDO = diaryService.findById(id);
        if (Objects.isNull(diaryDO) || diaryDO.getCreateType().equals(DiaryDO.CreateTypeEnums.DELETE.type)) {
            return BusinessResult.createInstance(CommonResultMessage.DIARY_NOT_EXIST);
        }
        DiaryVO diaryVO = diaryService.findDetail(diaryDO);
        perfectRootDiary(diaryVO);
        //补充点赞记录和是否为作者
        if (Objects.nonNull(currentUserId)) {
            List<Long> zanDiaryIdList = diaryZanService.ifDiaryZanByUserId(new ArrayList<>(Collections.singleton(id)), currentUserId);
            diaryVO.setZan(zanDiaryIdList.contains(diaryVO.getId()));
            diaryVO.setAuthor(currentUserId.equals(diaryVO.getUserId()));
        } else {
            diaryVO.setZan(false);
            diaryVO.setAuthor(false);
        }
        if (checkPlatformAndVersion(request)) {
            List<String> imgUrls = diaryVO.getImgUrls();
            if (!CollectionUtils.isEmpty(imgUrls) && imgUrls.size() > 6) {
                diaryVO.setImgUrls(imgUrls.subList(0, 6));
            }

            if (DiaryDO.CreateTypeEnums.FORWARD.type.equals(diaryVO.getCreateType())
                    && Objects.nonNull(diaryVO.getRootDiary())) {
                DiaryVO rootDiary = diaryVO.getRootDiary();
                List<String> rootDiaryImgUrls = rootDiary.getImgUrls();
                if (!CollectionUtils.isEmpty(rootDiaryImgUrls) && rootDiaryImgUrls.size() > 6) {
                    rootDiary.setImgUrls(rootDiaryImgUrls.subList(0, 6));
                }
            }
        }
        return BusinessResult.createSuccessInstance(diaryVO);
    }

    /**
     * 完善转发日记内容
     *
     * @param diaryVO diaryVO
     */
    private void perfectRootDiary(DiaryVO diaryVO) {
        if (diaryVO.getCreateType().equals(DiaryDO.CreateTypeEnums.FORWARD.type)) {
            DiaryVO rootDiary = diaryService.findDetail(diaryService.findById(diaryVO.getRootId()));
            diaryVO.setRootDiary(rootDiary);
        }
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "日记详情-评论列表", notes = "评论列表", position = 16)
    @GetMapping("/commentList")
    @AuthSig
    public BusinessResult<Page<UserDiaryCommentVO>> commentList(@ApiParam(value = "日记id", required = true) @RequestParam Long diaryId,
                                                                @ApiParam(value = "页码", required = true) @RequestParam(defaultValue = "1") Integer page,
                                                                @ApiParam(value = "页码大小", required = true) @RequestParam(defaultValue = "4") Integer size) {
        if (null == diaryId || page < 1 || size < 1) {
            return createInstance(CommonResultMessage.PARMAS_INVALID);
        }
        UserInfoDTO userInfoDTO = currentUser();
        if (null == userInfoDTO) {
            return createInstance(CommonResultMessage.USER_NOT_LOGIN);
        }

        try {
            Page<UserDiaryCommentVO> byDiaryIdFutrue = diaryService.commentPageByDiaryId(diaryId, userInfoDTO.getId(), page, size);
            return createSuccessInstance(byDiaryIdFutrue);
        } catch (Exception ex) {
            log.error("commentList error ,ex = {}", ex);
            return createInstance(CommonResultMessage.DIARY_FAIL);
        }
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "日记详情-点赞列表", notes = "日记点赞", position = 17)
    @GetMapping("/likeList")
    @AuthSig
    public BusinessResult<Page<UserDiaryZanVO>> zanList(@ApiParam(value = "日记id", required = true) @RequestParam Long targetId,
                                                        @ApiParam(value = "类型1:日记，3:回复", required = true) @RequestParam Integer type,
                                                        @ApiParam(value = "页码", required = true) @RequestParam(defaultValue = "1") Integer page,
                                                        @ApiParam(value = "页码大小", required = true) @RequestParam(defaultValue = "20") Integer size) {
        if (0 == targetId || null == UserDiaryZanDO.TypeEnums.create(type) || page < 1 || size < 1) {
            return createInstance(CommonResultMessage.PARMAS_INVALID);
        }
        try {
            Page<UserDiaryZanVO> byTargetIdAndType = diaryZanService.getByTargetIdAndType(targetId, type, page, size);
            return createSuccessInstance(byTargetIdAndType);
        } catch (Exception ex) {
            log.error("likeList error ,ex = {}", ex);
            return createInstance(CommonResultMessage.DIARY_FAIL);
        }
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "个人日记-分页", notes = "日记-分页", position = 21)
    @AuthSig
    @GetMapping("/page")
    public BusinessResult<Page<DiaryVO>> pageByUserId(HttpServletRequest request,
                                                      @ApiParam(value = "用户id", required = true) @RequestParam Long userId,
                                                      @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                                      @ApiParam(value = "页码大小") @RequestParam(defaultValue = "10") Integer pageSize) {

        if (Objects.isNull(userId)) {
            throw new IllegalArgumentException("userId 为空！");
        }
        log.debug("查询我的日记分页 page = {} pageSize = {}", page, pageSize);
        Long currentUserId = currentUserId();
        PageRequest pageRequest = new PageRequest((page - 1), pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);

        Page<DiaryVO> resultVO;
        if (userId.equals(currentUserId)) {
            resultVO = diaryService.page(null, userId, pageRequest, true);
        } else {
            if (Objects.isNull(currentUserId)) {
                resultVO = diaryService.page(null, userId, pageRequest, false);
            } else {
                BusinessResult<Integer> result = userFriendClient.checkBlacklist(currentUserId, userId);
                if (result.getData() == 1) {
                    resultVO = new Page<>(1, 0, Collections.emptyList());
                } else {
                    resultVO = diaryService.page(null, userId, pageRequest, false);
                }
            }
        }
        filter(resultVO, currentUserId, Collections.emptyList());
        //分页补充点赞记录
        perfectZanAuthor(currentUserId, resultVO);

        //补充转发日记内容
        resultVO.getRows().forEach(this::perfectRootDiary);
        filterImageCount(request, resultVO);
        return BusinessResult.createSuccessInstance(resultVO);
    }

    private void filterImageCount(HttpServletRequest request, Page<DiaryVO> resultVO) {
        if (checkPlatformAndVersion(request)) {
            List<DiaryVO> rows = resultVO.getRows();
            if (!CollectionUtils.isEmpty(rows)) {
                List<DiaryVO> diaryVOList = rows.stream().map(diaryVO -> {
                    List<String> imgUrls = diaryVO.getImgUrls();
                    if (!CollectionUtils.isEmpty(imgUrls) && imgUrls.size() > 6) {
                        diaryVO.setImgUrls(imgUrls.subList(0, 6));
                    }
                    if (DiaryDO.CreateTypeEnums.FORWARD.type.equals(diaryVO.getCreateType())
                            && Objects.nonNull(diaryVO.getRootDiary())) {
                        DiaryVO rootDiary = diaryVO.getRootDiary();
                        List<String> rootDiaryImgUrls = rootDiary.getImgUrls();
                        if (!CollectionUtils.isEmpty(rootDiaryImgUrls) && rootDiaryImgUrls.size() > 6) {
                            rootDiary.setImgUrls(rootDiaryImgUrls.subList(0, 6));
                        }
                    }
                    return diaryVO;
                }).collect(Collectors.toList());

                resultVO.setRows(diaryVOList);
            }
        }
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "关注-日记-分页", notes = "关注-日记-分页", position = 21)
    @AuthSig
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/follows/page")
    public BusinessResult<Page<DiaryVO>> followsDiaryPage(HttpServletRequest request,
                                                          @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                                          @ApiParam(value = "页码大小") @RequestParam(defaultValue = "10") Integer pageSize) {
        Long currentUserId = currentUserId();
        if (Objects.isNull(currentUserId)) {
            throw new IllegalArgumentException("userId 为空！");
        }
        log.debug("查询我的日记分页 page = {} pageSize = {}", page, pageSize);
        List<Long> followsList = userFriendClient.followsAll(currentUserId).getData().stream().map(UserFollowInfo::getFollowUserId).collect(Collectors.toList());
        PageRequest pageRequest = new PageRequest((page - 1), pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
        if (followsList.isEmpty()) {
            return BusinessResult.createSuccessInstance(new Page<DiaryVO>());
        }
        Page<DiaryVO> resultVO = diaryService.page(followsList, pageRequest);
        resultVO = filter(resultVO, currentUserId, Collections.emptyList());
        //分页补充点赞记录
        perfectZanAuthor(currentUserId, resultVO);

        //补充转发日记内容
        resultVO.getRows().forEach(this::perfectRootDiary);
        filterImageCount(request, resultVO);
        return BusinessResult.createSuccessInstance(resultVO);
    }


    @AutoLog
    @ApiOperation(value = "日记-学习圈首页-分页（根据话题搜索）", notes = "查询日记", position = 21)
    @AuthSig
    @GetMapping("/learning-circle/page")
    public BusinessResult<Page<DiaryVO>> page(HttpServletRequest request,
                                              @ApiParam(value = "话题id") @RequestParam(required = false) Long topicId,
                                              @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                              @ApiParam(value = "页码大小") @RequestParam(defaultValue = "10") Integer pageSize,
                                              @ApiParam(value = "创建时间") @RequestParam(required = false) String createTime) {

        Long currentUserId = currentUserId();
        if (StringUtils.isNotEmpty(createTime)) {
            page = 1;
        }
//        if (page == 1) {
//            pageSize = 20;
//        }
        PageRequest pageRequest = new PageRequest((page - 1), pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
        Page<DiaryVO> resultVO = diaryService.page(topicId, null, pageRequest, createTime);
        filter(resultVO, currentUserId, Collections.emptyList());
        int i = 0;
        while (resultVO.getRows().size() < 6 && i < 10) {
            log.info("违规日记过多，多次查询 i = {}", i);
            pageRequest = new PageRequest(pageRequest.getPageNumber() + 1, pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
            Page<DiaryVO> page2 = diaryService.page(topicId, null, pageRequest, createTime);
            resultVO.getRows().addAll(page2.getRows());
            filter(resultVO, currentUserId, Collections.emptyList());
            i++;
        }
        //分页补充点赞记录
        perfectZanAuthor(currentUserId, resultVO);

        //补充日记前四条评论
        resultVO.getRows().forEach(diaryVO -> {
            try {
                diaryVO.setCommentList(diaryReplyService.getDiaryListVO(diaryVO.getId(), 0, 4, diaryVO.getUserId()).get(10, TimeUnit.SECONDS));
            } catch (Exception e) {
                log.error("补充日记前四条评论错误");
            }
        });

        //补充转发日记内容
        resultVO.getRows().forEach(this::perfectRootDiary);
        filterImageCount(request, resultVO);
        return BusinessResult.createSuccessInstance(resultVO);
    }

    @AutoLog
    @ApiOperation(value = "v3.2.0 日记-学习圈首页-分页（根据话题搜索）", notes = "查询日记", position = 21)
    @AuthSig
    @GetMapping("/v3.2.0/learning-circle/page")
    public BusinessResult<Page<DiaryVO>> pageJoinAdvert(
            HttpServletRequest request,
            @ApiParam(value = "话题id") @RequestParam(required = false) Long topicId,
            @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
            @ApiParam(value = "页码大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @ApiParam(value = "创建时间") @RequestParam(required = false) String createTime) {
        UserInfoDTO user = currentUser();
        Long currentUserId = Objects.isNull(user) ? null : user.getId();

        PageRequest pageRequest = new PageRequest((page - 1), pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
        Page<DiaryVO> result = diaryService.page(topicId, null, pageRequest, createTime);

        //查询黑名单列表
        List<UserBlacklist> blacklists = new ArrayList<>();
        if (Objects.nonNull(currentUserId)) {
            BusinessResult<List<UserBlacklist>> userBlacklistResult = userFriendClient.myBlacklist(currentUserId);
            blacklists = userBlacklistResult.getData();
        }
        List<Long> blackIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(blacklists)) {
            blackIds = blacklists.stream().map(UserBlacklist::getFriendsUserId).collect(Collectors.toList());
        }
        filter(result, currentUserId, blackIds);
        int i = 0;
        while (result.getRows().size() < 6 && i < 10) {
            log.info("违规日记过多，多次查询 i = {}", i);
            pageRequest = new PageRequest(pageRequest.getPageNumber() + 1, pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
            Page<DiaryVO> page2 = diaryService.page(topicId, null, pageRequest, createTime);
            result.getRows().addAll(page2.getRows());
            filter(result, currentUserId, blackIds);
            i++;
        }
        //分页补充点赞记录
        perfectZanAuthor(currentUserId, result);

        //补充日记前四条评论
        result.getRows().forEach(diaryVO -> {
            try {
                diaryVO.setCommentList(diaryReplyService.getDiaryListVO(diaryVO.getId(), 0, 4, diaryVO.getUserId()).get(10, TimeUnit.SECONDS));
            } catch (Exception e) {
                log.error("补充日记前四条评论错误");
            }
        });

        //补充转发日记内容
        result.getRows().forEach(this::perfectRootDiary);

        String app = getApp(request);
        DicDO dicDO = dicService.findByCode(app.equals(AppEnum.postgraduate.name()) ? POSTGRADUATE_DIARY_ADVERT.dicName() : DIARY_ADVERT.dicName());
        String platform = getPlatform(request);
        Long switchCode;
        if (Platform.ios.name().equals(platform)) {
            switchCode = dicDO.filter(ios_switch.name()).getCode();
        } else if (Platform.android.name().equals(platform)) {
            switchCode = dicDO.filter(android_switch.name()).getCode();
        } else {
            switchCode = Math.max(dicDO.filter(ios_switch.name()).getCode(), dicDO.filter(android_switch.name()).getCode());
        }

        //每多少条数据展示一次
        long displayInterval = dicDO.filter(diary_display_interval.name()).getCode() / 10;
        if (switchCode == YN.YES.getCode()
                && !result.getRows().isEmpty()
                && page % displayInterval == 1
//                && (Objects.isNull(user) || !TargetFilter.contain(user.getCurrentLearnTargetName()))
                && Objects.isNull(topicId)
                && isStudyDay(app)
        ) {
            addAdvert(result, app);
            if (Objects.nonNull(currentUserId)) {
                //记录埋点数据
                buryingPointExecutor.execute(() -> {
                    DiaryVO advert = result.getRows().get(0);
                    BuryingPointVO point = BuryingPointVO.builder()
                            .modular(dicName().toLowerCase())
                            .function(advert.getAdvertType())
                            .operationType(BuryingPointOperationType.show.name())
                            .pointSite("diary")
                            .userId(currentUserId)
                            .build();
                    userCenterService.add(point);
                });
            }
        }
        filterImageCount(request, result);
        return BusinessResult.createSuccessInstance(result);
    }

    private boolean isStudyDay(String app){
        //考研自习室app，不受此影响
        if(AppEnum.postgraduate.name().equals(app)){
            return true;
        }
        String[] days = dicService.findByCode(STUDY_OPEN_DAYS.dicName())
                .filter(STUDY_OPEN_DAYS.days.name())
                .getData()
                .split(",");
        List<Date> studyDays = Arrays.stream(days).map(DateUtil::strToDate).collect(Collectors.toList());

        //没有设置开放日，直接返回
        if (studyDays.isEmpty()) {
            return false;
        }
        Date today = DateUtil.strToDate(DateUtil.getStringDateShort());
        Date date = studyDays.stream().filter(day -> {
            long l = day.getTime() - today.getTime();
            return l >= 0 && l / 1000 / 60 / 60 / 24 <= 2;
        }).findFirst().orElse(null);

        //是否为某个开放日前两天或当天，不是的话直接返回
        if (Objects.nonNull(date)) {
            return true;
        }
        return false;
    }

    /**
     * 增加广告
     *
     * @param resultVO
     */
    private void addAdvert(Page<DiaryVO> resultVO, String app) {
        List<DiaryVO> rows = resultVO.getRows();
        DicDO dicDO = dicService.findByCode(app.equals(AppEnum.postgraduate.name()) ? POSTGRADUATE_DIARY_ADVERT.dicName() : DIARY_ADVERT.dicName());
        String image = dicDO.filter(diary_advert_images.name()).getData();
        String url = dicDO.filter(diary_advert_url.name()).getData();
        String type = dicDO.filter(diary_advert_type.name()).getData();
        String h5Title = dicDO.filter(diary_h5_title.name()).getData();

        DiaryVO advert = DiaryVO.builder().type(DiaryVO.TypeEnums.advert.name())
                .advertImage(image)
                .advertUrl(url)
                .advertType(resultVO.getPageNumber() == 1 ? type + "_banner" : type)
                .diaryH5Title(h5Title)
                .createTime(resultVO.getRows().get(0).getCreateTime())
                .build();
        rows.add(0, advert);
    }

    private Page<DiaryVO> filter(Page<DiaryVO> resultVO, Long currentUserId, List<Long> blackIds) {
        List<DiaryVO> diaryList = resultVO.getRows();
        List<DiaryVO> collect = diaryList.stream().filter(diary -> {
            if (blackIds.contains(diary.getUserId())) {
                return false;
            }
            if (Objects.isNull(diary.getSeeByMyself())) {
                return true;
            }

//            if(Objects.isNull(currentUserId)){
//                return false;
//            }
            if (diary.getSeeByMyself().equals(YN.NO.getCode())) {
                return true;
            } else {
                return diary.getUserId().equals(currentUserId);
            }
        }).collect(Collectors.toList());
//        if(!diaryList.isEmpty() && collect.size()< 5){
//            return resultVO;
//        }
        resultVO.setRows(collect);
        return resultVO;
    }

    private void perfectZanAuthor(Long currentUserId, Page<DiaryVO> resultVO) {
        if (Objects.nonNull(currentUserId)) {
            List<Long> diaryIdList = resultVO.getRows().stream().map(DiaryVO::getId).collect(Collectors.toList());
            List<Long> zanDiaryIdList = diaryZanService.ifDiaryZanByUserId(diaryIdList, currentUserId);
            resultVO.getRows().forEach(diaryVO -> {
                diaryVO.setZan(zanDiaryIdList.contains(diaryVO.getId()));
                diaryVO.setAuthor(currentUserId.equals(diaryVO.getUserId()));
            });
        } else {
            resultVO.getRows().forEach(diaryVO -> {
                diaryVO.setZan(false);
                diaryVO.setAuthor(false);
            });
        }
    }


    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "日记-群动态-分页（内部调用）", notes = "查询日记", position = 21)
    @AuthSig
    @PostMapping("/group-dynamics/page")
    public BusinessResult<Page<DiaryVO>> pageInUserIds(
            @ApiParam(value = "当前登录用户id") @RequestParam Long currentUserId,
            @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
            @ApiParam(value = "页码大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @ApiParam(value = "群用户idList") @RequestBody List<Long> userIdList) {
        if (Objects.isNull(currentUserId)) {
            throw new IllegalArgumentException("currentUserId为空！");
        }
        if (Objects.isNull(userIdList) || userIdList.isEmpty()) {
            throw new IllegalArgumentException("userIdList为空！");
        }

        PageRequest pageRequest = new PageRequest((page - 1), pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
        Page<DiaryVO> resultVO = diaryService.page(userIdList, pageRequest);

        resultVO = filter(resultVO, currentUserId, Collections.emptyList());
        //分页补充点赞记录
        List<Long> diaryIdList = resultVO.getRows().stream().map(DiaryVO::getId).collect(Collectors.toList());
        List<Long> zanDiaryIdList = diaryZanService.ifDiaryZanByUserId(diaryIdList, currentUserId);
        resultVO.getRows().forEach(diaryVO -> {
            diaryVO.setZan(zanDiaryIdList.contains(diaryVO.getId()));
            diaryVO.setAuthor(currentUserId.equals(diaryVO.getUserId()));
        });

        //补充转发日记内容
        resultVO.getRows().forEach(this::perfectRootDiary);

        //补充日记前四条评论
        resultVO.getRows().forEach(diaryVO -> {
            try {
                diaryVO.setCommentList(diaryReplyService.getDiaryListVO(diaryVO.getId(), 0, 4, diaryVO.getUserId()).get(10, TimeUnit.SECONDS));
            } catch (Exception e) {
                log.error("补充日记前四条评论错误");
            }
        });
        return BusinessResult.createSuccessInstance(resultVO);
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "日记-群动态-分页（内部调用）", notes = "查询日记", position = 21)
    @AuthSig
    @GetMapping("/group-dynamics/page")
    public BusinessResult<Page<DiaryVO>> pageInUserId(
            @ApiParam(value = "当前登录用户id") @RequestParam Long currentUserId,
            @ApiParam(value = "群用户idList") @RequestParam List<Long> userIdList,
            @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
            @ApiParam(value = "页码大小") @RequestParam(defaultValue = "10") Integer pageSize) {
        if (Objects.isNull(currentUserId)) {
            throw new IllegalArgumentException("currentUserId为空！");
        }
        if (Objects.isNull(userIdList) || userIdList.isEmpty()) {
            throw new IllegalArgumentException("userIdList为空！");
        }
        PageRequest pageRequest = new PageRequest((page - 1), pageSize, Sort.Direction.DESC, DiaryDO.FILED_CREATE_TIME);
        Page<DiaryVO> resultVO = diaryService.page(userIdList, pageRequest);

        //分页补充点赞记录
        List<Long> diaryIdList = resultVO.getRows().stream().map(DiaryVO::getId).collect(Collectors.toList());
        List<Long> zanDiaryIdList = diaryZanService.ifDiaryZanByUserId(diaryIdList, currentUserId);
        resultVO.getRows().forEach(diaryVO -> {
            diaryVO.setZan(zanDiaryIdList.contains(diaryVO.getId()));
            diaryVO.setAuthor(currentUserId.equals(diaryVO.getUserId()));
        });

        //补充转发日记内容
        resultVO.getRows().forEach(this::perfectRootDiary);

        //补充日记前四条评论
        resultVO.getRows().forEach(diaryVO -> {
            try {
                diaryVO.setCommentList(diaryReplyService.getDiaryListVO(diaryVO.getId(), 0, 4, diaryVO.getUserId()).get(10, TimeUnit.SECONDS));
            } catch (Exception e) {
                log.error("补充日记前四条评论错误");
            }
        });
        return BusinessResult.createSuccessInstance(resultVO);
    }


    /**
     * 图片素材上传并上传至图床返回一个图片地址
     * type =  0：用户素材 1：gif 合成图 2：其他
     */
    @AutoLog
    @ApiOperation(value = "发布日记-图片上传", notes = "单个图片上传", position = 90)
    @RequestMapping(value = "/upload/image", method = RequestMethod.POST)
    public BusinessResult<List<String>> uploadImg(@ApiParam(value = "图片") @RequestBody MultipartFile[] files) throws IOException {
        if (files.length > MAX_UPLOAD_IMAGES) {
            throw new IllegalArgumentException("最多上传" + MAX_UPLOAD_IMAGES + "张图片！");
        }
        Objects.requireNonNull(currentUserId(), "请登录后上传图片！");
        List<Pair<String, String>> imageUrls = new ArrayList<>();
        for (MultipartFile file : files) {
            // 获取图片后缀名
            String resultSuffix = "";
            String originalFileName = file.getOriginalFilename();
            if (!org.apache.commons.lang.StringUtils.isBlank(originalFileName)) {
                int start = originalFileName.lastIndexOf(".");
                start = start == -1 ? 0 : start;
                String suffix = originalFileName.substring(start, originalFileName.length());
                resultSuffix = suffix.startsWith(".") ? suffix : "." + suffix;
            }
            resultSuffix = StringUtils.isBlank(resultSuffix) ? ".jpg" : resultSuffix;
            if (".jpeg".equalsIgnoreCase(resultSuffix)) {
                resultSuffix = ".jpg";
            }
            // 存储路径 格式 /tongzhuo/diary/user/id/
            String uploadRealPathDir = getUploadImgPath();
            String newName = UUID.randomUUID().toString() + resultSuffix;
            String localUploadFilePath = uploadRealPathDir + currentUserId() + "/" + newName;
            //上传到ali oss
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            File tempFile = File.createTempFile(UUID.randomUUID().toString(), suffix);
            // 将MultipartFile转为File
            file.transferTo(tempFile);

            cosClient.putObject(cosConfig.getBucketName(), localUploadFilePath, tempFile);
            String imageUrl = cosConfig.getImgDomain() + "/" + localUploadFilePath;
            imageUrls.add(Pair.of(imageUrl, localUploadFilePath));
            tempFile.delete();
            log.info("日记图片上传 imageUrl = {}", imageUrl);
        }
        for (Pair<String, String> pair : imageUrls) {
            Boolean flag = tencentImageCheckService.checkImg(pair.getFirst());
            if (flag) {
                imageUrls.forEach(pair1 -> cosClient.deleteObject(cosConfig.getBucketName(), pair1.getSecond()));
                return createInstance(IMAGE_VIOLATION);
            }
        }
        log.info("上传日记图片 imageUrls = {}", imageUrls);
        return createSuccessInstance(imageUrls.stream().map(Pair::getFirst).collect(Collectors.toList()));
    }


    @AutoLog
    @ApiOperation(value = "根据用户id查询日记数量", notes = "根据用户id查询日记数量", position = 90)
    @GetMapping("/count/by-user-id")
    public BusinessResult<Long> countByUserId(@RequestParam Long userId) {
        return BusinessResult.createSuccessInstance(diaryService.countByUserId(userId));
    }

    @AutoLog
    @ApiOperation(value = "删除日记", notes = "删除日记", position = 200)
    @PreAuthorize("isAuthenticated()")
    @DeleteMapping("/{id}")
    public BusinessResult delete(@PathVariable Long id) {
        DiaryDO diaryDO = diaryService.findById(id);

        if (Objects.isNull(diaryDO)) {
            throw new IllegalArgumentException("非法id id = " + id);
        }

        if (!diaryDO.getUserId().equals(currentUserId())) {
            throw new IllegalArgumentException("只能删除自己创建的日记 id = " + id);
        }

        if (diaryDO.getCreateType().equals(DiaryDO.CreateTypeEnums.DELETE.type)) {
            return BusinessResult.createInstance(DELETE_NOT_EXIST, "删除数据不存在！id = " + id);
        }
        diaryDO.setCreateType(DiaryDO.CreateTypeEnums.DELETE.type);
        diaryService.save(diaryDO);
        return BusinessResult.createSuccessInstance(null);
    }


    @Autowired
    private DiaryService diaryService;
    @Autowired
    private UserDiaryReplyService diaryCommentService;
    @Autowired
    private UserDiaryZanService diaryZanService;
    @Autowired
    private ForwardService forwardService;
    @Autowired
    private UserDiaryTopicService topicService;
    @Autowired
    private UserDiaryReplyService diaryReplyService;
    @Autowired
    private UserFriendClient userFriendClient;
    @Autowired
    private SocketClient socketClient;
    @Autowired
    private COSClient cosClient;
    @Autowired
    private COSConfig cosConfig;
    @Autowired
    private TencentImageCheckService tencentImageCheckService;
    @Autowired
    private DicServiceImpl dicService;
    @Resource(name = "buryingPointExecutor")
    private AsyncTaskExecutor buryingPointExecutor;

    public static final int MAX_UPLOAD_IMAGES = 9;

}